home *** CD-ROM | disk | FTP | other *** search
- .NLIST TTM,BEX
- .TITLE MC68000 CROSS ASSEMBLER SUPPORT
- ;
- ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;
- ; ASSEMBLY LANGUAGE SUBROUTINES FOR MC68000 CROSS-ASSEMBLER.
- ; FORTRAN LINKAGE TO THESE ROUTINES IS AS FOLLOWS:
- ; 1. RETURN VIA 'RTS PC'.
- ; 2. R5 POINTS TO PARAMETER LIST WITH FOLLOWING:
- ; A. NUMBER OF PARAMETERS.
- ; B. ADDRESS OF FIRST PARAMETER
- ; C. ADDRESS OF SECOND PARAMETER, ETC.
- ; 3. FUNCTION SUBROUTINES (INTEGER) RETURN VALUE IN R0.
- ;
- ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;
- ; ** I4CLR **
- ;
- ; CLEAR LOW AND HIGH WORDS OF DOUBLE PRECISION VARIABLE
- ; ADR OF LOW WORD PASSED VIA (R5)
- ;
- I4CLR:: TST (R5)+
- MOV R0,-(SP)
- MOV (R5),R0
- CLR (R0)+
- CLR (R0)
- MOV (SP)+,R0
- RTS PC
- ;
- ; ** GETBIT **
- ;
- ; SUBROUTINE TO CONVERT 4 LSB OF A INTEGER*2 VARIABLE TO A HEX
- ; ASCII DIGIT. THE INTEGER IS IN THE FIRST PARAMETER AND THE
- ; HEX DIGIT IS RETURNED IN THE SECOND PARAMETER (BYTE). THE
- ; INTEGER IS SHIFTED RIGHT BY 4 BEFORE RETURNING.
- ;
- CNVTBL: .ASCII '0123456789ABCDEF'
- GETBIT:: MOV R0,-(SP) ;
- MOV @2(R5),R0 ;GET WORD
- BIC #177760,R0 ;MASK OUT 4 LSB
- MOVB CNVTBL(R0),@4(R5) ;CONVERT AND RETURN
- MOV @2(R5),R0 ;SHIFT INPUT INTEGER
- ASH #-4,R0 ; RIGHT BY 4.
- MOV R0,@2(R5) ;
- MOV (SP)+,R0 ;
- RTS PC ;RETURN
- .PAGE
- ;
- ; ** ICKVAL **
- ;
- ; INTEGER FUNCTION TO CHK IF I*2 VARIABLE IS IN THE RANGE
- ; -64,63. IF IT IS A VALUE OF 0 IS RETURNED, OTHERWISE
- ; A VALUE OF ONE IS RETURNED
- ;
- ICKVAL:: MOV @2(R5),R0
- BIT #177600,R0
- BEQ 10$
- BIC #177,R0
- CMP R0,#177600
- BEQ 10$
- MOV #1,R0
- RTS PC
- 10$: CLR R0
- RTS PC
- .PAGE
- ;
- ; THE FOLLOWING INTEGER*4 ARITHMETIC ROUTINES ARE USED INSTEAD
- ; OF F4P CALLS TO PERMIT THE CROSS ASSEMBLER TO RUN WITHOUT
- ; MODIFICATIONS ON EITHER RT-11 OR RSX-11 SYSTEMS
- ;
- JADD:: CLR R0 ;INITIALIZE FOR NORMAL EXIT
- TST (R5)+ ;SKIP COUNT ARG
- MOV (R5)+,R4 ;ADDR OF OPERAND 1
- MOV (R5)+,R3 ;ADDR OF OPERAND 2
- MOV (R5)+,R1 ;ADDR OF RESULT
- MOV (R4)+,R2 ;GET LOW ORDER OP 1
- ADD (R3)+,R2 ;ADD IN LOW ORDER OP 2
- MOV @R4,R5 ;GET HIGH ORDER OP 1
- ADC R5 ;ADD IN CARRY
- BVS 1$
- ADD @R3,R5 ;ADD IN HIGH ORDER OP 2
- BVC 2$
- 1$: CLR R2 ;SET RESULT TO 0
- CLR R5
- MOV #-2,R0 ;INDICATE OVERFLOW
- 2$: MOV R2,(R1)+ ;STORE RESULT
- MOV R5,@R1
- RTS PC
- .PAGE
- ;
- ; INTEGER*4 SUBTRACTION
- ;
- JSUB:: CLR R0 ;INITIALIZE FOR NORMAL EXIT
- TST (R5)+ ;SKIP COUNT ARG
- MOV (R5)+,R4 ;ADDR OF OPERAND 1
- MOV (R5)+,R3 ;ADDR OF OPERAND 2
- MOV (R5)+,R1 ;ADDR OF RESULT
- MOV (R4)+,R2 ;GET LOW ORDER OP 1
- SUB (R3)+,R2 ;SUBTRACT LOW ORDER OP 2
- MOV @R4,R5 ;GET HIGH ORDER RESULT
- SBC R5 ;SUBTRACT CARRY
- BVS 1$
- SUB @R3,R5 ;SUBTRACT HIGH ORDER OP 2
- BVC 2$
- 1$: CLR R2 ;SET RESULT TO 0
- CLR R5
- MOV #-2,R0 ;INDICATE OVERFLOW
- 2$: MOV R2,(R1)+ ;STORE RESULT
- MOV R5,@R1
- RTS PC
- .PAGE
- ;
- ; INTEGER*4 MULTIPLICATION
- ;
- JMUL:: TST (R5)+ ;SKIP COUNT ARG
- CLR -(SP) ;INIT SIGN FLAG
- MOV (R5)+,R4 ;ADDR OF OPERAND 1
- MOV (R4)+,R1 ;GET LOW ORDER OP 1
- MOV @R4,R3 ;GET HIGH ORDER OP 1
- BPL 1$ ;BRNCH IF POSITIVE
- NEG R3 ;TAKE ABSOLUTE VALUE
- NEG R1
- SBC R3
- INC @SP ;AND SET SIGN FLAG
- 1$: MOV (R5)+,R4 ;ADDR OF OPERAND 2
- MOV (R4)+,R0 ;LOW ORDER OF OP 2
- MOV @R4,R2 ;HIGH ORDER OF OP 2
- BPL 2$ ;BRAANCH IF POSITIVE
- INC @SP ;SET SIGN FLAG
- NEG R2 ;AND TAKE ABSOLUTE VALUE
- NEG R0
- SBC R2
- 2$: BEQ 3$ ;BRANCH IF HIGH PART OF OP 2 IS 0
- TST R3 ;IF WASN'T OP 2 MUST BE OP 1
- BNE OVRFL ;BRANCH IF RESULT WILL BE TOO BIG
- MOV R0,R4 ;OTHERWISE SWITCH OPS
- MOV R1,R0
- MOV R4,R1
- MOV R2,R3
- CLR R2
- 3$: CLR R4 ;RESULT WILL END UP IN R2:R4
- 4$: ROR R0 ;SHIFT BIT OUT OF MULTIPLIER
- BCC 5$ ;BRANCH IF 0
- ADD R1,R4 ;ADD LOW PARTS TOGETHER
- ADC R2 ;ADD IN CARRY
- BVS OVRFL ;BRANCH IF OVERFLOW
- ADD R3,R2 ;ADD HIGH PARTS TOGETHER
- BVS OVRFL ;BRANCH IF OVERFLOW
- TST R0 ;ANY MORE OF MULTIPLIER LEFT?
- 5$: BEQ DONE ;BRANCH IF FINISHED
- ASL R1 ;SHIFT MULTIPLICAND LEFT
- ROL R3
- BVC 4$ ;LOOP
- OVRFL: MOV #-2,R0 ;SET OVEFLOW INDICATOR
- CLR R2 ;SET RESULT TO 0
- CLR R4
- DONE: ROR (SP)+ ;GET RESULT SIGN INTO C
- BCC 1$ ;BRANCH IF TO BE POSITIVE
- NEG R2 ;NEGATE RESULT
- NEG R4
- SBC R2
- 1$: MOV @R5,R1 ;ADDR OF RESULT
- MOV R4,(R1)+ ;STORE LOW ORDER
- MOV R2,@R1 ;STORE HIGH ORDER
- RTS PC
- .PAGE
- ;
- ; INTEGER*4 DIVISION
- ;
- JDIV:: CLR -(SP) ;SET SUCCCESSFUL EXIT FLAG
- MOV (R5)+,-(SP) ;SAVE ARG COUNT
- MOV (R5)+,R4 ;ADDR OF NUMERATOR
- MOV (R5)+,R1 ;ADDR OF DENOMINATOR
- MOV R5,-(SP) ;SAVE ADDR OF RESULT
- MOV #33.,-(SP) ;SET SHIFT COUNTER
- MOV (R1)+,R0 ;GET LOW ORDER DENOM
- MOV @R1,R1 ;GET HIGH ORDER DENOM
- BPL 1$ ;BRANCH IF POSITIVE
- NEG R1 ;TAKE ABSOLUTE VALUE
- NEG R0
- SBC R1
- ADD #100000,@SP ;AND SET SIGN FLAG
- 1$: BNE 2$ ;BRANCH IF DENOM CAN'T BE 0
- TST R0 ;MAKE SURE LOW DENOM ISN'T 0
- BEQ ZDIV ;BRANCH IF ZERO DIVIDE
- 2$: MOV (R4)+,R2 ;LOW ORDER OF NUM
- MOV @R4,R3 ;HIGH ORDER OF NUM
- BPL 3$ ;BRANCH IF POSITIVE
- ADD #40000,@SP ;SET SIGN FLAG
- NEG R3 ;AND TAKE ABSOLUTE VALUE
- NEG R2
- SBC R3
- 3$: CLR R5 ;QUOTIENT ENDS UP IN R3:R2
- CLR R4 ;REMAINDER ENDS UP IN R5:R4
- 4$: ROL R4 ;EXPOSE NEW BIT OF NUMERATOR
- ROL R5
- CMP R1,R5 ;DOES DENOM FIT?
- BHI 6$ ;BRANCH IF NOT, C=0
- BNE 5$ ;BRANCH IF YES
- CMP R0,R4 ;HIGH PARTS SAME, CHECK LOW
- BHI 6$ ;BRANCH IF NOT, C=0
- 5$: SUB R0,R4 ;SUBTRACT DENOM FROM REMAINDER
- SBC R5
- SUB R1,R5
- SEC ;INDICATE NEW QUOTIENT BIT
- 6$: ROL R2 ;SHIFT IN NEW BIT OF QUOTIENT
- ROL R3
- DECB @SP ;CHECK LOOP COUNT
- BGT 4$ ;BRANCH TO LOOP
- ENDCOD: ASL @SP ;PUT QUOTIENT RESULT SIGN IN V
- BVC 1$ ;BRANCH IF TO BE POSITIVE
- NEG R3 ;NEGATE QUOTIENT
- NEG R2
- SBC R3
- 1$: TST (SP)+ ;GET REMAINDERS SIGN
- BPL 2$ ;BRANCH IF REMAINDER TO BE POSITIVE
- NEG R5 ;NEGATE REMAINDER
- NEG R4
- SBC R5
- 2$: MOV (SP)+,R0 ;GET ARG LIST POINTER AGAIN
- MOV (R0)+,R1 ;ADDR OF QUOTIENT RESULT
- CMPB #3,(SP)+ ;CHECK NUMBER OF ARGUMENTS
- BEQ 3$ ;BRANCH IF ONLY 3 PASSED
- MOV @R0,R0 ;GET ADDR REMAINDER RESULT
- MOV R4,(R0)+ ;STORE LOW
- MOV R5,@R0 ;STORE HIGH
- 3$: MOV R2,(R1)+ ;STORE LOW QUOTIENT RESULT
- MOV R3,@R1 ;STORE HIGH
- TST (SP)+
- RTS PC
- ZDIV: CLR R4 ;SET REMAINDER TO 0
- CLR R5
- CLR R2 ;SET QUOTIENT TO 0
- CLR R3
- MOV #-3,6(SP) ;SET ZDIV ERROR INDICATOR
- BR ENDCOD ;GO SET RESULTS
- .PAGE
- ;
- ; INTEGER*4 LOGICAL AND
- ;
- JAND:: TST (R5)+ ;SKIP COUNT ARGUMENT
- MOV (R5)+,R0 ;ADR OF NUMBER
- MOV (R5)+,R1 ;ADR OF NUMBER TO BE ANDED
- MOV (R5)+,R2 ;ADR OF DESTINATION
- MOV (R0)+,R3 ;GET VAL OF HIGH PART OF NUMBER
- MOV (R1)+,R4 ;GET VAL OF HIGH PART OF MASK
- COM R4 ;INVERT MASK BITS
- BIC R4,R3 ;AND 'EM
- MOV R3,(R2)+ ;STORE RESULT IN DESTINATION
- MOV (R0),R3 ;GET VAL OF LOW PART OF NUMBER
- MOV (R1),R4 ;GET VAL OF LOW PART OF MASK
- COM R4 ;INVERT MASK BITS
- BIC R4,R3 ;AND 'EM
- MOV R3,(R2) ;STORE RESULT IN DESTINATION
- CLR R0 ;CLR VAL OF FUNCTION
- RTS PC
- .PAGE
- ;
- ; INTEGER*4 INCLUSIVE OR
- ;
- JOR:: TST (R5)+ ;SKIP OVER ARGUMENT COUNT
- MOV (R5)+,R0 ;ADR OF NUMBER
- MOV (R5)+,R1 ;ADR OF NUMBER TO BE OR'ED
- MOV (R5)+,R2 ;ADR OF DESTINATION
- MOV (R0)+,R3 ;GET VAL OF HIGH PART OF NUMBER
- MOV (R1)+,R4 ;GET VAL OF HIGH PART OF OR MASK
- BIS R4,R3 ;OR 'EM
- MOV R3,(R2)+ ;STORE RESULT IN DESTINATION
- MOV (R0),R3 ;GET VAL OF LOW PART OF NUMBER
- MOV (R1),R4 ;GET VAL OF LOW PART OF OR MASK
- BIS R4,R3 ;OR 'EM
- MOV R3,(R2) ;STORE RESULT IN DESTINATION
- CLR R0 ;STD FUNCTION RETURN VAL
- RTS PC
- .PAGE
- ;
- ; ** JLSHF **
- ;
- ; INTEGER*4 LEFT SHIFT (UNSIGNED)
- ;
- JLSHF:: TST (R5)+ ;SKIP OVER ARGUMENT COUNT
- MOV (R5),R0 ;SRC ADR
- MOV @2(R5),R1 ;NUMBER OF BITS TO SHIFT IT
- MOV 4(R5),R2 ;DEST ADR
- MOV (R0)+, (R2) ;MOVE SRC TO DEST
- MOV (R0) ,2(R2)
- TST R1
- BEQ 99$ ;SHIFTING 0 BITS IS SILLY
- CMP R1,#40
- BHI 99$ ;CAN'T SHIFT MORE THAN 32 BITS
- 1$: CLC ;MAKE SURE CARRY IS CLEAR
- ROL (R2) ;SHIFT LO HALF 1 BIT
- ROL 2(R2) ;SHIFT HI WRD
- 3$: DEC R1 ;DECR #BITS TO SHIFT
- BNE 1$ ;LOOP IF NON ZERO
- ;
- 99$: CLR R0
- RTS PC
- .PAGE
- ;
- ; ** JRSHF **
- ;
- ; INTEGER*4 RIGHT SHIFT (UNSIGNED)
- ;
- JRSHF:: TST (R5)+ ;SKIP OVER ARGUMENT COUNT
- MOV (R5),R0 ;ADR OF NUMBER TO SHIFT
- MOV @2(R5),R1 ;NUMBER OF BITS TO SHIFT IT
- MOV 4(R5),R2 ;DESTINATION ADDRESS
- MOV (R0)+, (R2) ;MOVE SRC TO DEST
- MOV (R0) ,2(R2)
- TST R1
- BEQ 99$ ;SHIFTING 0 BITS IS SILLY
- CMP R1,#40
- BHI 99$ ;CAN'T SHIFT MORE THAN 32 BITS
- 1$: CLC ;MAKE SURE CARRY IS CLEAR
- ROR 2(R2) ;SHIFT HI HALF 1 BIT
- ROR (R2) ;SHIFT LO WRD
- DEC R1 ;DECR #BITS TO SHIFT
- BNE 1$ ;LOOP IF NON ZERO
- ;
- 99$: CLR R0
- RTS PC
- .PAGE
- ;
- ; ** JICMP **
- ;
- ; COMPARE A 32 BIT SIGNED NUMBER WITH A 16 BIT SIGNED NUMBER
- ; FUNCTION RETURNS A VALUE OF ZERO IF THE NUMBERS ARE EQUIVALENT
- ;
- JICMP:: TST (R5)+
- MOV (R5)+,R0 ;ADR OF I*4 VALUE
- MOV @(R5)+,R1 ;VALUE OF I*2 NUMBER
- TST R1 ;SEE IF VAL NEGATIVE
- BPL 1$ ;
- CMP (R0),#177777 ;SEE IF NUMBER NEGATIVE
- BNE 99$ ;NUMBER NOT NEGATIVE
- BR 2$
- 1$: TST (R0) ;IF I*2 NUMBER NOT NEG THEN HI WORD
- BNE 99$ ;MUST BE ZERO
- 2$: CMP 2(R0),R1 ;CMP THE TWO NUMBERS
- BNE 99$
- CLR R0
- RTS PC ;NUMBERS ARE EQUAL
- 99$: MOV #1,R0 ;NUMBERS NOT EQUAL
- RTS PC
- .PAGE
- ;
- ; ** JMOV **
- ;
- ; INTEGER*4 MOVE
- ;
- JMOV:: CLR R0 ;INITIALIZE FOR NORMAL EXIT
- TST (R5)+ ;SKIP COUNT ARG
- MOV (R5)+,R4 ;ADDR OF OPERAND 1
- MOV (R5)+,R1 ;ADDR OF OPERAND 2
- MOV (R4)+,(R1)+ ;MOVE LOW PART
- MOV @R4,@R1 ;MOVE HIGH PART
- RTS PC
- .PAGE
- ;
- ; ** BLDMAP (DLIST,ALIST,OUTPUT) **
- ;
- ; CREATE A REGISTER BITMAP FROM A DATA AND ADR REG MAP
- ;
- BLDMAP:: TST (R5)+ ;SKIP OVER ARG COUNT
- MOV @(R5)+,R0 ;GET DATA BITMAP
- BIC #177400,R0 ;MAKE SURE NO EXTRA BITS SET
- MOV @(R5)+,R1 ;GET ADR BITMAP
- BIC #177400,R1 ;MAKE SURE NO EXTRA BITS SET
- SWAB R1 ;MOVE ADR REG BITS UP WHERE THEY BELONG
- BIS R0,R1 ;OR IN THE D-REG BITS
- MOV R1,@(R5) ;SAVE THE RESULT IN THE DESTINATION
- RTS PC ;AND RETURN
- .PAGE
- ;
- ; ** JICVT (I*2,I*4 RESULT) **
- ;
- ; I*2 TO I*4 CONVERSION (SIGNED)
- ;
- JICVT:: TST (R5)+ ;SKIP COUNT ARG
- CLR R2 ;INIT SIGN EXTEND WORD
- MOV @(R5)+,R0 ;GET INTEGER VALUE
- BPL 1$ ;BRANCH IF POSITIVE
- DEC R2 ;SET SIGN EXTEND WORD
- 1$: MOV @R5,R1 ;ADDR OF RESULT
- MOV R0,(R1)+ ;STORE LOW ORDER
- MOV R2,@R1 ;STORE HIGH ORDER
- CLR R0 ;INITIALIZE FOR NORMAL EXIT
- RTS PC
- .END